﻿namespace SERFLITEMAX20.Core
{
    using System;
    using System.Collections;
    using System.Reflection;

    internal abstract class BaseHashtable
    {
        internal int basePtr;
        private int lastPtr;
        internal Main owner;
        private Hashtable ptrs;
        internal Hashtable table;

        internal BaseHashtable(Main owner)
        {
            this.owner = owner;
            this.lastPtr = 0;
            this.table = new Hashtable();
            this.ptrs = new Hashtable();
        }

        internal virtual bool ContainsKey(object key)
        {
            return this.table.ContainsKey(key);
        }

        internal abstract object GetKey(int nPtr);
        internal int GetPointer(object key)
        {
            object obj2 = this.ptrs[key];
            if (obj2 == null)
            {
                return 0;
            }
            return (int) obj2;
        }

        internal abstract object GetValue(int nPtr);
        internal void Update()
        {
            int nPtr = 0;
            if (((this.lastPtr == 0) || (this.lastPtr == 0x1c)) || ((this.lastPtr & 1) != 0))
            {
                this.lastPtr = this.owner.Memory.ReadInteger(this.basePtr + 20);
            }
            nPtr = this.lastPtr;
            while ((((nPtr & 1) == 0) && (nPtr != 0)) && (nPtr != 0x1c))
            {
                object key = this.GetKey(nPtr);
                if (!this.table.ContainsKey(key))
                {
                    object obj3 = this.GetValue(nPtr);
                    if (obj3 != null)
                    {
                        this.table.Add(key, obj3);
                        this.ptrs.Add(key, nPtr);
                    }
                }
                this.lastPtr = nPtr;
                nPtr = this.owner.Memory.ReadInteger(nPtr + 0x10);
                if (nPtr == this.lastPtr)
                {
                    break;
                }
            }
        }

        internal void UpdateAll()
        {
            int nPtr = 0;
            this.lastPtr = 0;
            this.lastPtr = this.owner.Memory.ReadInteger(this.basePtr + 20);
            nPtr = this.lastPtr;
            while ((((nPtr & 1) == 0) && (nPtr != 0)) && (nPtr != 0x1c))
            {
                object key = this.GetKey(nPtr);
                if (!this.table.ContainsKey(key))
                {
                    object obj3 = this.GetValue(nPtr);
                    if (obj3 != null)
                    {
                        this.table.Add(key, obj3);
                        this.ptrs.Add(key, nPtr);
                    }
                }
                this.lastPtr = nPtr;
                nPtr = this.owner.Memory.ReadInteger(nPtr + 0x10);
                if (nPtr == this.lastPtr)
                {
                    break;
                }
            }
        }

        internal int BasePtr
        {
            get
            {
                return this.basePtr;
            }
        }

        internal int Count
        {
            get
            {
                return this.ptrs.Count;
            }
        }

        internal virtual object this[object key]
        {
            get
            {
                return this.table[key];
            }
        }
    }
}

